using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using System;
using System.Windows;
using System.IO;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using ExcelMergeDocs.WinClient.Services;
using GalaSoft.MvvmLight.Messaging;

namespace ExcelMergeDocs.WinClient.ViewModel {
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase {

        #region fields
        private IDocSelectionService _docSelectionService;
        #endregion


        #region CTOR
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel() {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real"
            ////}

        }

        public MainViewModel(IDocSelectionService docSelectionService) {
            // TODO: Complete member initialization
            this._docSelectionService = docSelectionService;
        }
        #endregion

        #region Documents
        private ObservableCollection<DocViewModel> _documents;
        public ObservableCollection<DocViewModel> Documents {
            get {
                return _documents ?? (_documents = new ObservableCollection<DocViewModel>());
            }
        }
        #endregion

        private void LookBusy(Action action) {
            //IsBusy = true;
            action();
            //IsBusy = false;
        }

        #region IsBusy
        private bool _isBusy;
        private const string IsBusyPropertyName = "IsBusy";

        public bool IsBusy {
            get { return _isBusy; }
            set {
                if (_isBusy != value) {
                    RaisePropertyChanged(IsBusyPropertyName, _isBusy, value, true);
                    _isBusy = value;
                }
            }
        }
        #endregion

        #region FileDroppedCommand
        private RelayCommand<DragEventArgs> _fileDroppedCommand;



        /// <summary>
        /// Gets the TestCommand.
        /// </summary>
        public RelayCommand<DragEventArgs> FileDroppedCommand {
            get {
                return _fileDroppedCommand ?? (_fileDroppedCommand = new RelayCommand<DragEventArgs>(
                    p => {
                        if (p.Data == null) return;

                        var files = p.Data.GetData(DataFormats.FileDrop) as string[];
                        if (files == null || files.Count() == 0) return;

                        LookBusy(() => {
                            //
                            // directories
                            files.Where(f => Directory.Exists(f))
                                .SelectMany(f => f.GetFiles(new[] { "*.xls" }, SearchOption.AllDirectories))
                                .Where(w => !Documents.Any(a => a.Name == w))
                                .ToList()
                                .ForEach(f => {
                                    Documents.Add(_docSelectionService.LoadDocument(f));
                                });
                            //
                            // files
                            files
                                .Where(f => File.Exists(f))
                                .Where(f => new[] { ".xls", ".xlsx" }.Contains(Path.GetExtension(f)))
                                .Where(w => !Documents.Any(a => a.Name == w))
                                .ToList()
                                .ForEach(f => {
                                    Documents.Add(_docSelectionService.LoadDocument(f));
                                });
                        });

                    },
                    p => {
                        return true;
                    }));
            }
        }
        #endregion

        #region ProcessCommand
        private RelayCommand _processCommand;

        /// <summary>
        /// Gets the TestCommand.
        /// </summary>
        public RelayCommand ProcessCommand {
            get {
                return _processCommand ?? (_processCommand = new RelayCommand(
                    () => {
                        LookBusy(() => {
                            _docSelectionService.MergeDocuments(Documents);
                        });
                    },
                    () => {
                        return Documents
                            .SelectMany(s => s.Worksheets)
                            .Any(s => s.IsSelected);
                    }));
            }
        }
        #endregion

        #region ClearAllCommand
        #region ClearAllCommand
        private RelayCommand _clearAllCommand;

        /// <summary>
        /// Gets the TestCommand.
        /// </summary>
        public RelayCommand ClearAllCommand {
            get {
                return _clearAllCommand ?? (_clearAllCommand = new RelayCommand(
                    () => {
                        Documents.Clear();
                    },
                    () => {
                        // CanExecute delegate
                        return Documents.Count > 0;
                    }));
            }
        }
        #endregion

        #endregion
    }
}